﻿using System;
using System.Collections.Generic;
using FluentNHibernate.Automapping;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using MPBlog.Model;
using MPBlog.Model.FluentNhibernateMap;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Criterion;

namespace MPBlog.DAL
{
    public class BaseDao<T> where T : class
    {
        #region - variable -

        private static Configuration configuration =
             Fluently.Configure()
            .Database(MsSqlConfiguration.MsSql2000
                     .ConnectionString(s => s
                     .Server("111.68.9.42")
                     .Database("MPBlog")
                     .Username("a0216215226")
                     .Password("scott"))
                     .ShowSql())
            .Mappings(m => m
                     .FluentMappings
                     .AddFromAssembly(typeof(ArticleMap).Assembly))
            .BuildConfiguration();

        //Fluently.Configure().Database(MsSqlConfiguration.MsSql2005.ConnectionString(s => s
        //    .Server(@"CNSZLC4001WXP\SQLEXPRESS")
        //    .Database("MPBlog")
        //    .TrustedConnection()).ShowSql())
        //    .Mappings(m => m.FluentMappings.AddFromAssembly(typeof(ArticleMap).Assembly))  //fluent map
        //    .BuildConfiguration();

        /// <summary>
        /// 使用单例模式创建SessionFactory
        /// </summary>
        private static readonly ISessionFactory sessionFactory = configuration.BuildSessionFactory();

        #endregion

        #region - property -

        /// <summary>
        /// 获得数据库配置信息
        /// </summary>
        public static Configuration Configuration
        {
            get { return configuration; }
        }

        /// <summary>
        /// 创建新的Session
        /// </summary>
        public static ISession NHibernateSession
        {
            get { return sessionFactory.OpenSession(); }
        }

        #endregion

        #region -Basic operation（增，删，改，查）-

        /// <summary>
        /// 新增一个实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public T Create(T entity)
        {
            //为了保证 操作事物和具体操作的session一致，这个是必须的
            using (ISession session = NHibernateSession)
            using (ITransaction transaction = session.BeginTransaction())
            {
                try
                {
                    session.Save(entity);
                    transaction.Commit();
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw;
                }
            }
            return entity;
        }

        /// <summary>
        /// 更新一个实体
        /// </summary>
        /// <param name="entity"></param>
        public bool Update(T entity)
        {
            using (ISession session = NHibernateSession)
            using (ITransaction transaction = session.BeginTransaction())
            {
                try
                {
                    session.Update(entity);
                    transaction.Commit();
                    return true;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    return false;
                }
            }
        }

        /// <summary>
        /// 删除一个实体
        /// </summary>
        /// <param name="entity"></param>
        public bool Delete(T entity)
        {
            using (ISession session = NHibernateSession)
            using (ITransaction transaction = session.BeginTransaction())
            {
                try
                {
                    session.Delete(entity);
                    transaction.Commit();
                    return true;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    return false;
                }
            }
        }

        /// <summary>
        /// 删除一个实体
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool Delete(int id)
        {
            using (ISession session = NHibernateSession)
            using (ITransaction transaction = session.BeginTransaction())
            {
                try
                {
                    T entity = session.Get<T>(id);
                    session.Delete(entity);
                    transaction.Commit();
                    return true;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    return false;
                }
            }
        }

        /// <summary>
        /// 获得一个实体
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public T GetById(int id)
        {
            T entity;
            using (ISession session = NHibernateSession)
            using (ITransaction transaction = session.BeginTransaction())
            {
                try
                {
                    entity = session.Get<T>(id);
                    transaction.Commit();
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw;
                }
            }
            return entity;
        }

        /// <summary>
        /// 查询相似条件的对象集合
        /// </summary>
        /// <param name="criterions">不定条件</param>
        /// <param name="projections">投影条件</param>
        /// <returns></returns>
        public IList<T> GetList(IEnumerable<ICriterion> criterions, IEnumerable<IProjection> projections)
        {
            using (ISession session = NHibernateSession)
            {
                ICriteria ca = session.CreateCriteria<T>();
                if (criterions != null)
                {
                    foreach (ICriterion criteria in criterions)
                    {
                        ca.Add(criteria);
                    }
                }
                if (projections != null)
                {
                    foreach (IProjection projection in projections)
                    {
                        ca.SetProjection(projection);
                    }
                }
                return ca.List<T>();
            }
        }


        /// <summary>
        /// 查询相似条件的对象集合
        /// </summary>
        /// <param name="criterions">不定条件</param>
        /// <returns></returns>
        public IList<T> GetList(params ICriterion[] criterions)
        {
            using (ISession session = NHibernateSession)
            {
                ICriteria ca = session.CreateCriteria<T>();

                foreach (ICriterion criteria in criterions)
                {
                    ca.Add(criteria);
                }

                return ca.List<T>();
            }
        }

        #endregion

        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="pageIndex">当前页</param>
        /// <param name="pageSize">每页显示数量</param>
        /// <param name="property">排序的字段(不需要排序则为null)</param>
        /// <param name="asc">是否正序排列</param>
        /// <param name="criterias">筛选条件</param>
        /// <returns></returns>
        public IList<T> GetPage(int pageIndex, int pageSize, string property, bool asc, IEnumerable<ICriterion> criterias)
        {
            IList<T> list;
            using (ISession session = NHibernateSession)
            using (ITransaction transaction = session.BeginTransaction())
            {
                try
                {
                    ICriteria ca = session.CreateCriteria<T>();
                    if (criterias != null)
                    {
                        foreach (ICriterion criteria in criterias)
                        {
                            ca.Add(criteria);
                        }
                    }

                    if (property != null)
                    {
                        list = ca.SetFirstResult((pageIndex - 1) * pageSize)
                            .SetMaxResults(pageSize)
                            .AddOrder(new Order(property, asc))
                            .List<T>();
                    }
                    else
                    {
                        list = ca.SetFirstResult((pageIndex - 1) * pageSize)
                            .SetMaxResults(pageSize)
                            .List<T>();
                    }
                    transaction.Commit();
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw;
                }
            }
            return list;
        }

        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="pageIndex">当前页</param>
        /// <param name="pageSize">每页显示数量</param>
        /// <param name="property">排序的字段(不需要排序则为null)</param>
        /// <param name="asc">是否正序排列</param>
        /// <param name="criterias">筛选条件</param>
        /// <param name="allRecords">总共有多少条记录</param>
        /// <returns></returns>
        public IList<T> GetPage(int pageIndex, int pageSize, string property, bool asc, IEnumerable<ICriterion> criterias, out int allRecords)
        {
              using (ISession session = NHibernateSession)
              {
                  ICriteria ca = session.CreateCriteria<T>();
                  if (criterias != null)
                  {
                      foreach (ICriterion criteria in criterias)
                      {
                          ca.Add(criteria);
                      }
                  }
                  allRecords = ca.List<T>().Count;
              }

            return GetPage(pageIndex, pageSize, property, asc, criterias);
        }
    }
}